/**
 * Copyright 2010, Lars J. Nilsson <http://www.larsan.net> 
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.larsan.dconf;

import java.util.List;
import java.util.Map;

/**
 * <p>This is a node in a configuration hierarchy. Nodes
 * may be created on the fly, depending on implementation,
 * so for example, the following <i>may</i> not be true:</p>
 * 
 * <pre>
 *    node.getParent() == node.getParent()
 * </pre>
 * 
 * <p>However, node equality will stay the same, based on the 
 * node path. The children, parent or attributes are not included
 * in node equality. So, the following will always be
 * true (for a node with a parent):</p>
 * 
 * <pre>
 *    node.getParent().equals(node.getParent());
 * </pre>
 * 
 * <p>For a discussion about node paths and domains, please refer
 * to the {@link DPath} documentation. </p>
 * 
 * @author Lars J. Nilsson
 */
public interface DNode extends PropertiesHandler {
	
	
	/**
	 * @return The path of the node, never null
	 */
	public DPath getPath();

	
	/**
	 * @return The parent of the current node, or null if root
	 */
	public DNode getParent();
	
	
	/**
	 * @return The node store this node belongs to, never null
	 */
	public DNodeStore getStore();
	
	
	/**
	 * This method returns a list of children for the current node. The
	 * returned list will be immutable. 
	 * 
	 * @return An immutable list of child nodes, never null
	 */
	public List<DNode> getChildren();
	
	
	/**
	 * This method retrieves a child of this node, and optionally
	 * creates it if it does not exist. The name must adhere to the 
	 * same rules as spelled out in {@link DPath#child(String)}.
	 * 
	 * @param name Name of the child, must not be null or contains ':' or '/'
	 * @param create True to create the child if it does not exist, false otherwise
	 * @return The node child if found or created, or null
	 */
	public DNode getChild(String name, boolean create);

	
	/**
	 * Get all attributes of the current node. This method 
	 * returns an immutable map.
	 * 
	 * @return An immutable map of all attributes, never null
	 */
	public Map<String, String> getAttributes();

	
	/**
	 * @param key Attribute name, must not be null
	 * @return The attribute value, or null if not found
	 */
	public String getAttribute(String key);

	
	/**
	 * @param key Attribute name, must not be null
	 * @param val Attribute value, must not be null
	 * @return Any previous value, or null
	 */
	public String setAttribute(String key, String val);
	
	
	/**
	 * @param key Attribute name, must not be null
	 * @return Attribute value if found, or null
	 */
	public String removeAttribute(String key);
	
	
	/**
	 * @param key Attribute name, must not be null
	 * @return True if the attribute exists, false otherwise
	 */
	public boolean hasAttribute(String key);
	
	
	/**
	 * Visit this node and all descendants. This method is always
	 * recursive down all child nodes.
	 *  
	 * @param visitor Visitor to use, must not be null
	 */
	public void visit(DNodeVisitor visitor);
	
	
	/**
	 * Delete this node. This will remove the node from the 
	 * underlying node store.
	 */
	public void remove();

}
